from django import forms
from django.contrib.auth import authenticate
from django.contrib.auth.models import User
import time
from django.conf import settings


class LoginForm(forms.Form):
    username = forms.CharField(
        label='用户名',
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': '请输入用户名/或邮箱',
            'autofocus': 'autofocus'
        }
        ),
        error_messages={'required': '用户名或邮箱不能为空'}
    )
    password = forms.CharField(
        label='密码', widget=forms.PasswordInput(attrs={
            'class': 'form-control',
            'placeholder': '请输入密码'
        }))

    def clean(self):
        username_or_email = self.cleaned_data['username']
        password = self.cleaned_data['password']
        if not username_or_email:
            raise forms.ValidationError('用户名或密码不正确')
        user = authenticate(username=username_or_email, password=password)
        if user is None:
            if User.objects.filter(email=username_or_email).exists():
                username = User.objects.get(email=username_or_email).username
                user = authenticate(
                    username=username, password=password)
                if user:
                    self.cleaned_data['user'] = user
                    return self.cleaned_data
            raise forms.ValidationError('用户名或密码不正确')
        else:
            self.cleaned_data['user'] = user
        return self.cleaned_data


class RegForm(forms.Form):
    username = forms.CharField(
        label='用户名', widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': '请输入用户名'
        }))
    email = forms.EmailField(
        label='邮箱', widget=forms.EmailInput(attrs={
            'class': 'form-control',
            'placeholder': '请输入邮箱'
        }))
    verification_code = forms.CharField(
        label='验证码',
        required=False,
        widget=forms.TextInput(
            attrs={
                'class': 'form-control',
                'placeholder': '点击"发送验证码"'
            }
        )
    )
    password = forms.CharField(
        label='密码', min_length=6, max_length=32, widget=forms.PasswordInput(
            attrs={
                'class': 'form-control',
                'placeholder': '请输入密码'
            }
        )
    )
    password_again = forms.CharField(
        label='确认密码', min_length=6, max_length=32,
        widget=forms.PasswordInput(attrs={
            'class': 'form-control',
            'placeholder': '请再次输入密码'
        }
        )
    )

    def __init__(self, *args, **kwargs):
        if 'request' in kwargs:
            self.request = kwargs.pop('request')
        super(RegForm, self).__init__(*args, **kwargs)

    def clean(self):
        # 判断验证码
        code = self.request.session.get('register_code', '')
        verification_code = self.cleaned_data.get('verification_code', '')
        if not (code != '' and code == verification_code):
            raise forms.ValidationError('验证码不正确')
        # 判断验证码是否失效
        now = int(time.time())
        send_code_time = self.request.session.get('send_code_time', 0)
        if now - send_code_time > 300:
            raise forms.ValidationError('验证码已失效')
        return self.cleaned_data

    def clean_username(self):
        username = self.cleaned_data['username']
        if User.objects.filter(username=username).exists():
            raise forms.ValidationError('用户名已存在')
        return username

    def clean_email(self):
        email = self.cleaned_data['email']
        if User.objects.filter(email=email).exists():
            raise forms.ValidationError('邮箱已存在')
        return email

    def clean_password_again(self):
        password = self.cleaned_data['password']
        password_again = self.cleaned_data['password_again']
        if password_again != password:
            raise forms.ValidationError('两次输入的密码不相同')
        return password

    def clean_verification_code(self):
        verification_code = self.cleaned_data.get(
            'verification_code', '').strip()
        if not verification_code:
            raise forms.ValidationError('验证码不能为空')
        return verification_code


class ChangeNicknameForm(forms.Form):
    nickname_new = forms.CharField(
        label='新的昵称', widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': '请输入新的昵称',
        })
    )

    def __init__(self, *args, **kwargs):
        if 'user' in kwargs:
            self.user = kwargs.pop('user')
        super(ChangeNicknameForm, self).__init__(*args, **kwargs)

    def clean(self):
        if self.user.is_authenticated:
            self.cleaned_data['user'] = self.user
        else:
            raise forms.ValidationError('用户尚未登录')
        return self.cleaned_data

    def clean_nickname_new(self):
        nickname_new = self.cleaned_data.get('nickname_new', '').strip()
        if not nickname_new:
            raise forms.ValidationError('新的昵称不能为空')
        return nickname_new


class BindEmailForm(forms.Form):
    email = forms.EmailField(
        label='邮箱', widget=forms.EmailInput(attrs={
            'class': 'form-control',
            'placeholder': '请输入有效的邮箱地址'
        })
    )
    verification_code = forms.CharField(
        label='验证码',
        required=False,
        widget=forms.TextInput(
            attrs={
                'class': 'form-control',
                'placeholder': '点击"发送验证码"'
            }
        )
    )

    def __init__(self, *args, **kwargs):
        if 'request' in kwargs:
            self.request = kwargs.pop('request')
        super(BindEmailForm, self).__init__(*args, **kwargs)

    def clean(self):
        # 判断用户是否登录
        if self.request.user.is_authenticated:
            self.cleaned_data['user'] = self.request.user
        else:
            raise forms.ValidationError('用户尚未登录')
        # 判断用户是否已经绑定邮箱
        if self.request.user.email != '':
            raise forms.ValidationError('你已经绑定了邮箱，不能再次绑定')
        # 判断验证码
        code = self.request.session.get('bind_email_code', '')
        verification_code = self.cleaned_data.get('verification_code', '')
        if not (code != '' and code == verification_code):
            raise forms.ValidationError('验证码不正确')

        # 判断验证码是否失效
        now = int(time.time())
        send_code_time = self.request.session.get('send_code_time', 0)
        if now - send_code_time > settings.TIME_OUT:
            raise forms.ValidationError('验证码已失效')
        return self.cleaned_data

    def clean_email(self):
        email = self.cleaned_data['email']
        if User.objects.filter(email=email).exists():
            raise forms.ValidationError('邮箱已经被绑定')
        return email

    def clean_verification_code(self):
        verification_code = self.cleaned_data.get(
            'verification_code', '').strip()
        if not verification_code:
            raise forms.ValidationError('验证码不能为空')
        return verification_code


class ChangePasswordForm(forms.Form):
    old_pass = forms.CharField(
        label='旧密码', widget=forms.PasswordInput(attrs={
            'class': 'form-control',
            'placeholder': '请输入旧密码'
        }),
        error_messages={'required': '密码不能为空'}
    )
    new_pass = forms.CharField(
        label='新密码', widget=forms.PasswordInput(attrs={
            'class': 'form-control',
            'placeholder': '请输入新密码'
        }))
    new_pass_again = forms.CharField(
        label='确认新密码', widget=forms.PasswordInput(attrs={
            'class': 'form-control',
            'placeholder': '请再次输入新密码'
        }))

    def __init__(self, *args, **kwargs):
        if 'user' in kwargs:
            self.user = kwargs.pop('user')
        super(ChangePasswordForm, self).__init__(*args, **kwargs)

    def clean(self):
        # 验证新的密码是否一致
        new_pass = self.cleaned_data.get('new_pass', '')
        new_pass_again = self.cleaned_data.get('new_pass_again', '')
        if new_pass != new_pass_again or new_pass == '':
            raise forms.ValidationError('两次输入的新密码不一致')
        return self.cleaned_data

    def clean_old_pass(self):
        # 验证旧的密码
        old_pass = self.cleaned_data.get('old_pass', '')
        if not self.user.check_password(old_pass):
            raise forms.ValidationError('旧的密码错误')
        return old_pass


class ForgetPasswordForm(forms.Form):
    email = forms.EmailField(
        label='邮箱', widget=forms.EmailInput(attrs={
            'class': 'form-control',
            'placeholder': '请输入绑定的邮箱地址'
        }))

    new_pass = forms.CharField(
        label='新密码', widget=forms.PasswordInput(attrs={
            'class': 'form-control',
            'placeholder': '请输入新密码'
        }))
    verification_code = forms.CharField(
        label='验证码',
        required=False,
        widget=forms.TextInput(
            attrs={
                'class': 'form-control',
                'placeholder': '点击"发送验证码"'
            }))

    def __init__(self, *args, **kwargs):
        if 'request' in kwargs:
            self.request = kwargs.pop('request')
        super(ForgetPasswordForm, self).__init__(*args, **kwargs)

    def clean_email(self):
        email = self.cleaned_data['email']
        if not User.objects.filter(email=email).exists():
            raise forms.ValidationError('邮箱不存在')
        return email

    def clean_verification_code(self):
        # 验证验证码
        verification_code = self.cleaned_data.get(
            'verification_code', '').strip()
        if not verification_code:
            raise forms.ValidationError('验证码不能为空')
        # 判断验证码
        code = self.request.session.get('forget_password_code', '')
        if not (code != '' and code == verification_code):
            raise forms.ValidationError('验证码不正确')
        # 判断验证码是否失效
        now = int(time.time())
        send_code_time = self.request.session.get('send_code_time', 0)
        if now - send_code_time > settings.TIME_OUT:
            raise forms.ValidationError('验证码已失效')
        return verification_code
